import re
import io
import base64
import qrcode


class PlateServer:
    def __init__(self, plate_no):
        self.plate_no = plate_no

    @property
    def is_valid(self):
        pattern_str = "^([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}" \
                      "(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|" \
                      "([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))$|" \
                      "^([0-9]{6}使)$|^((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)$|" \
                      "^(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})$|" \
                      "^([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})$"

        if re.match(pattern_str, self.plate_no):
            return True
        else:
            return False


class PhoneServer:
    def __init__(self, number):
        self.number = number
        self._cmcc = r'^1(3[4-9]|4[7]|5[012789]|7[28]|8[23478]|98)\d{8}$'
        self._cucc = r'^1(3[0-2]|4[5]|5[56]|66|7[156]|8[56])\d{8}$'  # 中国联通
        self._ctcc = r'^1(3[34]|4[9]|5[3]|7[347]|8[019]|99)\d{8}$'  # 中国电信
        self._v_cmcc = r'^1(70[356789]|71[0-9]|147)\d{8}$'  # 中国移动虚拟
        self._v_cucc = r'^1(70[4789]|71[019]|1719)\d{8}$'  # 中国联通虚拟
        self._v_ctcc = r'^1(700|701|702|62|65)\d{8}$'  # 中国电信虚拟

    @property
    def is_valid(self):
        return True if self.carrier else False

    @property
    def carrier(self):
        if re.match(self._cmcc, self.number):
            return '中国移动'
        if re.match(self._cucc, self.number):
            return '中国联通'
        if re.match(self._ctcc, self.number):
            return '中国电信'
        if re.match(self._v_cmcc, self.number):
            return '中国移动（虚拟运营商）'
        if re.match(self._v_cucc, self.number):
            return '中国联通（虚拟运营商）'
        if re.match(self._v_ctcc, self.number):
            return '中国电信（虚拟运营商）'
        return None


class QrcodeServer:
    def __init__(self, data):
        self.data = data

    def get_qrcode(self):
        """
        :return:
        qrcode.constants.ERROR_CORRECT_X：
            1. X=L时，大约7%或更少的错误能被纠正。
            2. X=M（默认）时，大约15%或更少的错误能被纠正。
            3. X=Q时，25%以下的错误会被纠正。
            4. X=H时，大约30%或更少的错误能被纠正。
        box_size：控制二维码中每个小格子包含的像素数。
        border：控制边框（二维码与图片边界的距离）包含的格子数（默认为4)
        version：值为1~40的整数，控制二维码的大小（最小值是1，是个21×21的矩阵）
        error_correction：控制二维码的错误纠正功能。可取值下列4个常量：
        """
        qr = qrcode.QRCode(version=5, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=8, border=4)
        # 向二维码中添加信息
        qr.add_data(self.data)
        qr.make(fit=True)
        img = qr.make_image()
        # 打开logo图片
        return img

    def get_base64_code(self):
        img = self.get_qrcode()
        byte_io = io.BytesIO()
        img.save(byte_io, 'PNG')
        code_base_64 = byte_io.getvalue()
        byte_io.close()
        return base64.b64encode(code_base_64).decode('utf-8')


if __name__ == '__main__':
    print(PhoneServer('14763315451').is_valid)
